Skip to content

feat(contexts): carry the menu through export and import - #3138

Open
rubenvdlinde wants to merge 2 commits into
feat/noid/app-menu-modelfrom
feat/noid/app-menu-export-import
Open

rubenvdlinde wants to merge 2 commits into
feat/noid/app-menu-modelfrom
feat/noid/app-menu-export-import

Conversation

@rubenvdlinde

@rubenvdlinde rubenvdlinde commented Oct 22, 2026 •

Copy link
Copy Markdown

Part of the stack on #3133, on top of #3135 (menu API). Implements the export and import part of the menu proposal on #3100. A menu now travels with its application through a scheme export and import, and when a user's data is moved to another instance. This replaces #3138.

Size: 537 lines: 320 code, 192 tests and 25 generated OpenAPI.

What changes

  • Export writes each item with pages by technical name, tables and views by uuid (by the table's technical name once Technical name for tables and applications, CRUD routes by application and table #3094 lands), and the group of an item by the group's position in the exported menu. Items have no technical name. The title an item shows is written along, for the preview.
  • Import replaces the menu. It finds pages by technical name and tables and views among the nodes of the application, the way importContext() maps nodes, so a menu never adds a table to an application. Every item is checked like the API checks it; an item that fails or whose target didn't come along is skipped and logged with the reason, and so is every item past the 200th. An item whose group didn't come before it, or was skipped, moves to the top level.
  • Moving a user's data (TablesMigrator) carries the menu: links, items for the moved application's pages, and items for the moved table. View items are skipped for now, because that import has no mapping from old view ids to new ones.
  • The scheme preview shows the menu the import would save next to the current one, and the items it would skip.
  • The import screen has a Menu switch, like Resources. When it's on (the default), the menu from the file is sent with the import; when it's off, the application keeps its menu.

How it was tested

On Nextcloud 34 with PostgreSQL:

  • MenuServiceTest against the database: a menu with a group, a link, a table and a page through a scheme export and importScheme(); a user migration through importContext(); items an import can't use, each skipped with its reason (data provider); an item whose group didn't come first moves to the top
  • by hand with curl: export, preview with a skipped item, and import of a menu into another application
  • the full unit suite on PostgreSQL and SQLite: 613 tests
  • composer cs:check, psalm and rector, all clean; npm run lint, npm run stylelint, npm run typescript:check and npm run build
  • Cypress component test ImportContextSchemePreview.cy.js: the import sends the menu, leaves it out when the switch is off, lists skipped items, and has no menu section without a menu

🖼️ Screenshots

One small UI change: the Menu switch on the import screen, with the menu before and after and the items that would be skipped.

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not needed
  • 🔙 Backport requests are created or not needed: /backport to stableX.X
  • 📅 Milestone is set
  • 🌸 PR title is meaningful (if it should be in the changelog: is it meaningful to users?)

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI

@samin-z samin-z left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you @rubenvdlinde

i tested the pr manually for now, what i found is the API part works fine, the exported file contains 'menuItems' and the import saves them when they are in the body. however the import screen does not send them.

from what i see, ImportContextSchemePreview.vue builds the import body in emitPayload() from the name, icon,description, tables and nodes. 'menuItems' is left out, so the application keeps the menu it already has. the preview response already returns the menu under 'menuItem' and it needs to be included in the import request, otherwise a user of the screen never gets the menu from the file.

@rubenvdlinde
rubenvdlinde force-pushed the feat/noid/app-menu-export-import branch from bfdf4e9 to e2404c1 Compare October 30, 2026 09:51
@rubenvdlinde

Copy link
Copy Markdown
Author

Thanks @samin-z, good catch. The preview already returned the menu, but the screen never sent it with the import.

The import screen now has a Menu switch, like Title, Icon and Resources. It shows the current menu, the menu after the import, and the items that would be skipped. When the switch is on (the default), the import sends the menu from the file. When it's off, the application keeps the menu it has. A Cypress component test covers both cases.

@rubenvdlinde
rubenvdlinde marked this pull request as draft November 2, 2026 11:14
@rubenvdlinde
rubenvdlinde force-pushed the feat/noid/app-menu-export-import branch 2 times, most recently from 511e6ca to a1b94a7 Compare November 2, 2026 11:23
rubenvdlinde added a commit that referenced this pull request Nov 3, 2026
…heme import

Importing a scheme skipped a node whose uuid was unknown and answered
200, but answered 403 for a node on a table or view the user cannot
manage. Such a node is now skipped the same way as an unknown one,
unless it already belongs to the application, the way the menu of
#3138 skips its items. A table to modify that is not here or cannot be
managed is refused with the same 400 in both cases.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ruben van der Linde <ruben@conduction.nl>
@rubenvdlinde
rubenvdlinde force-pushed the feat/noid/app-menu-export-import branch from a1b94a7 to 2471ff4 Compare November 3, 2026 14:51
The menu now travels with its application through a scheme export and
import, and when a user's data is moved to another instance.

An export writes each item with pages by technical name, tables and
views by uuid, and the group of an item by the group's position in the
exported menu. The title it shows is written along, for the import
preview. An import replaces the menu: it finds pages by technical
name and tables and views among the nodes of the application, so a menu
never adds a table to it. Every item is checked like the API checks it,
and an item that fails or whose target did not come along is skipped and
logged with the reason, as is every item past the 200th. An item whose
group did not come before it, or was skipped, moves to the top level.

Moving a user's data keeps the links, the items for the pages and the
items for the moved table. View items are skipped, as that import has no
mapping from old view ids to new ones yet.

The scheme preview shows the menu the import would save, next to the
current one, and the items it would skip. The import screen has a Menu
switch, like Resources: when it is off, the application keeps its menu.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ruben van der Linde <ruben@conduction.nl>
Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ruben van der Linde <ruben@conduction.nl>
@rubenvdlinde
rubenvdlinde removed this pull request from stack #3139 November 4, 2026 10:41
@rubenvdlinde
rubenvdlinde changed the base branch from feat/noid/app-menu-nesting to feat/noid/app-menu-model November 4, 2026 10:41
@rubenvdlinde
rubenvdlinde force-pushed the feat/noid/app-menu-export-import branch from 2471ff4 to 6368c26 Compare November 4, 2026 12:35
@rubenvdlinde
rubenvdlinde added this pull request to stack #3222 November 5, 2026 09:14
@rubenvdlinde

Copy link
Copy Markdown
Author

@samin-z could you review this one again?

@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

(If you believe you should not receive this message, you can add yourself to the blocklist.)

@rubenvdlinde
rubenvdlinde marked this pull request as ready for review November 6, 2026 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants